import { useState, useEffect, forwardRef, useImperativeHandle } from 'react'
import { EditOutlined, FormOutlined } from '@ant-design/icons';
import { Tooltip, Space } from 'antd';
import Draw from 'ol/interaction/Draw';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import { Fill, Stroke, Style } from 'ol/style';
import { LineString, Polygon } from 'ol/geom';
import { unByKey } from 'ol/Observable';
import { getArea, getLength } from 'ol/sphere.js';
import { Overlay } from 'ol';
import './index.less';
import useMap from '../../../hooks/useMap.js';
import DarkBtn from '../../../../../../../common/DarkBtn/index.js';
const source = new VectorSource();

const vector = new VectorLayer({
    source: source,
    style: {
        'fill-color': 'rgba(255, 255, 255, 0.2)',
        'stroke-color': '#ffcc33',
        'stroke-width': 2,
        'circle-radius': 7,
        'circle-fill-color': '#ffcc33',
    },
});
vector.set('temp', true)
let sketch;
let measureTooltipElement;
let measureTooltip;
let helpTooltipElement;
let helpTooltip;
let draw;
const continuePolygonMsg = '双击结束绘制';
const continueLineMsg = '双击结束绘制';
const Measure = forwardRef((props, ref) => {
    const map = useMap();
    useImperativeHandle(ref, () => {
        return {
            clear: () => {
                map.removeInteraction(draw);
                if (helpTooltipElement) {
                    helpTooltipElement.parentNode.removeChild(helpTooltipElement);
                    helpTooltipElement = null
                }
                if (measureTooltipElement) {
                    measureTooltipElement.parentNode.removeChild(measureTooltipElement);
                    measureTooltipElement = null;
                }
            }
        }
    })
    useEffect(() => {
        if (map) {
            map.addLayer(vector);
            map.on('pointermove', pointerMoveHandler);
            map.getViewport().addEventListener('mouseout', function () {
                helpTooltipElement && helpTooltipElement.classList.add('hidden');
            });
        }
    }, [map])

    const formatLength = function (line) {
        const length = getLength(line, {
            projection: 'EPSG:4326'
        });
        let output;
        if (length > 100) {
            output = `${(Math.round((length / 1000) * 100) / 100)} km`;
        } else {
            output = `${(Math.round(length * 100) / 100)} m`;
        }
        return output;
    };

    /**
     * Format area output.
     * @param {Polygon} polygon The polygon.
     * @return {string} Formatted area.
     */
    const formatArea = function (polygon) {
        const area = getArea(polygon, {
            projection: 'EPSG:4326'
        });
        let output;
        if (area > 10000) {
            output = `${Math.round((area / 1000000) * 100) / 100} km<sup>2</sup>`;
        } else {
            output = `${Math.round(area * 100) / 100} m<sup>2</sup>`;
        }
        return output;
    };
    function createHelpTooltip() {
        if (helpTooltipElement) {
            helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'ol-tooltip hidden';
        helpTooltip = new Overlay({
            element: helpTooltipElement,
            offset: [15, 0],
            positioning: 'center-left',
        });
        map.addOverlay(helpTooltip);
    }
    function createMeasureTooltip() {
        if (measureTooltipElement) {
            measureTooltipElement.parentNode.removeChild(measureTooltipElement);
        }
        measureTooltipElement = document.createElement('div');
        measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
        measureTooltip = new Overlay({
            element: measureTooltipElement,
            offset: [0, -15],
            positioning: 'bottom-center',
            stopEvent: false,
            insertFirst: false,
        });
        map.addOverlay(measureTooltip);
    }
    const pointerMoveHandler = function (evt) {
        if (evt.dragging || !helpTooltipElement) {
            return;
        }
        /** @type {string} */
        let helpMsg = '单击地图开始绘制';

        if (sketch) {
            const geom = sketch.getGeometry();
            if (geom instanceof Polygon) {
                helpMsg = continuePolygonMsg;
            } else if (geom instanceof LineString) {
                helpMsg = continueLineMsg;
            }
        }

        helpTooltipElement.innerHTML = helpMsg;
        helpTooltip.setPosition(evt.coordinate);

        helpTooltipElement.classList.remove('hidden');
    };
    function addInteraction(type) {
        // const type = typeSelect.value == 'area' ? 'Polygon' : 'LineString';
        draw = new Draw({
            source: source,
            type: type,
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)',
                }),
                stroke: new Stroke({
                    color: 'rgba(0, 0, 0, 0.5)',
                    lineDash: [10, 10],
                    width: 2,
                }),
            }),
            stopClick: true
        });
        map.addInteraction(draw);

        createMeasureTooltip();
        createHelpTooltip();

        let listener;
        draw.on('drawstart', function (evt) {
            // set sketch
            sketch = evt.feature;

            /** @type {import("../src/ol/coordinate.js").Coordinate|undefined} */
            let tooltipCoord = evt.coordinate;

            listener = sketch.getGeometry().on('change', function (evt) {
                const geom = evt.target;
                let output;
                if (geom instanceof Polygon) {
                    output = formatArea(geom);
                    tooltipCoord = geom.getInteriorPoint().getCoordinates();
                } else if (geom instanceof LineString) {
                    output = formatLength(geom);
                    tooltipCoord = geom.getLastCoordinate();
                }
                measureTooltipElement.innerHTML = output;
                measureTooltip.setPosition(tooltipCoord);
            });
        });

        draw.on('drawend', function (e) {
            e.stopPropagation();
            measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
            measureTooltip.setOffset([0, -7]);
            // unset sketch
            sketch = null;
            // unset tooltip so that a new one can be created
            measureTooltipElement = null;
            createMeasureTooltip();
            unByKey(listener);
            map.removeInteraction(draw);
            if (helpTooltipElement) {
                helpTooltipElement.parentNode.removeChild(helpTooltipElement);
                helpTooltipElement = null
            }
        });
    }

    return <Space direction="vertical" >
        <DarkBtn icon={<EditOutlined />} title="测距离" onClick={e => {
            map.removeInteraction(draw);
            addInteraction('LineString')
        }}></DarkBtn>
        <DarkBtn icon={<FormOutlined />} title="测面积" onClick={e => {
            map.removeInteraction(draw);
            addInteraction('Polygon')
        }}></DarkBtn>
    </Space>;
})

export default Measure;